﻿using MyTestProject.Core;
using MyTestProject.NUnity;
using MyTestProject.NUnity.MVVM;
using MyTestProject.NUnity.TcpClient;
using MyTestProject.Themes.ImageButton;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace MyTestProject.ViewModel
{
    /// <summary>
    /// 配置文件ViewModel
    /// </summary>
    public class ConfigViewModel : ObservableObject
    {
        public DataGrid DataGridVi { get; set; }
        private Thread _socketThread;
        private TcpClientDo _client;
        public ConfigViewModel(DataGrid dataGrid)
        {
            // 初始化tcp客户端
            _client = new TcpClientDo(this.ServerIP, this.Port);
            _client.CommRxEvent += _client_CommRxEvent;
            _client.Connect();
            _client.StartCommIdle();
            /// ReadFormSocket线程连接
            _socketThread = new Thread(_client.ReadFormSocket);
            _socketThread.IsBackground = false;
            _socketThread.Start();
            DataGridVi = dataGrid;
            string data = ReadWriteTxtHelper.ReadTxt();
            string[] datas = data.Split('@');
            for (var i = 1; i < datas.Length; i++)
            {
                string[] temp = datas[i].Split(new string[] { "\t" }, StringSplitOptions.None);
                Add(new ConfigModel() { Name = temp[0], InitialValue = temp[1], Unit = temp[2], Value = temp[3] });
                //第一次加载时将有的数据发给服务端
                SendData(temp[3]);
            }
            // 如数据为空时，新增一条空数据
            if (DataSourse.Count == 0)
            {
                DataSourse.Add(new ConfigModel() { AddBtVisibility = Visibility.Visible });
            }

            // 排序--采用倒序
            DataSourse.Sort<ConfigModel>(OrderByOption.Desc);
            DataSourse[DataSourse.Count - 1].AddBtVisibility = Visibility.Visible;
        }

        private void _client_CommRxEvent()
        {
            //接收数据操作,除此之外还可以注册接收事件,有数据来时读取
            byte[] recv = new byte[100];
            _client.CommReceive(recv, 100);
            string msg = Encoding.Default.GetString(recv);
            // 收到数据写入日志
            Logger.WriteLog1("TcpReciveData", msg);
        }

        private ObservableCollection<ConfigModel> _DataSourse = new ObservableCollection<ConfigModel>();

        /// <summary>
        /// 配置文件数据源
        /// </summary>
        public ObservableCollection<ConfigModel> DataSourse
        {
            get { return _DataSourse; }
            set
            {
                _DataSourse = value;
                RaisePropertyChanged("DataSourse");
            }
        }

        private string _ServerIP = "127.0.0.1";
        /// <summary>
        /// Ip
        /// </summary>
        public string ServerIP
        {
            get { return _ServerIP; }
            set
            {
                _ServerIP = value;
                RaisePropertyChanged("ServerIP");
            }
        }

        private int _Port = 5000;
        /// <summary>
        /// 端口
        /// </summary>
        public int Port
        {
            get { return _Port; }
            set
            {
                _Port = value;
                RaisePropertyChanged("Port");
            }
        }


        #region 业务操作

        /// <summary>
        /// 新增
        /// </summary>
        public void Add(ConfigModel config)
        {
            DataSourse.Add(config);
        }

        /// <summary>
        /// 更新
        /// </summary>
        public void Update(ConfigModel config)
        {
            for (var i = 0; i < DataSourse.Count; i++)
            {
                if (DataSourse[i].Id == config.Id)
                {
                    DataSourse[i].InitialValue = config.InitialValue;
                    DataSourse[i].Value = config.Value;
                    DataSourse[i].Unit = config.Unit;
                    break;
                }
            }
        }

        /// <summary>
        /// 添加配置项命令
        /// </summary>
        public ICommand SaveConfigItemCommand
        {

            get
            {
                return new RelayCommand(() =>
                {

                    for (var i = 0; i < DataSourse.Count; i++)
                    {
                        if (DataSourse[i].IsNewAdd && DataSourse[i].IsValidated())
                        {
                            DataSourse[i].IsNewAdd = false;
                            //新增一条数据，发送一条
                            SendData(DataSourse[i].Value);
                            // 不采用追加方式
                            //ReadWriteTxtHelper.WriteAppendTxt($"{DataSourse[i].Name}\t{DataSourse[i].InitialValue}\t\t{DataSourse[i].Unit}\t{DataSourse[i].Value}");
                        }
                    }
                    // 采用直接全部保存方式，解决修改配置侯，可以重新保存最新数据
                    ReSaveData();
                });
            }
        }

        /// <summary>
        /// 保存配置
        /// </summary>
        public ICommand AddItemConfigCommand
        {

            get
            {
                return new RelayCommand(() =>
                {
                    DataSourse[DataSourse.Count - 1].AddBtVisibility = Visibility.Collapsed;
                    DataSourse.Add(new ConfigModel() { AddBtVisibility = Visibility.Visible, IsNewAdd = true });
                    DataGridScrollToEnd();

                });
            }
        }

        /// <summary>
        /// 删除选择项
        /// </summary>
        public ICommand DeleteConfigItemCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    int count = this.DataSourse.Count;
                    for (var i = 0; i < count; i++)
                    {
                        if (this.DataSourse[i].IsSelected)
                        {
                            this.DataSourse.Remove(this.DataSourse[i]);
                            count--;
                            i--;
                        }
                    }
                    if (this.DataSourse.Count == 0)
                    {
                        ReSaveData();
                        this.DataSourse.Add(new ConfigModel() { AddBtVisibility = Visibility.Visible });
                    }
                    else
                    {
                        DataSourse[count - 1].AddBtVisibility = Visibility.Visible;
                        ReSaveData();
                    }
                });
            }
        }

        /// <summary>
        /// 单项删除命令
        /// </summary>
        public ICommand DeleteCommand
        {

            get
            {
                return new RelayCommand<ImageButtonNoSelect>((e) =>
                {
                    Delete(e.Tag.ToString());
                    if (DataSourse.Count > 0)
                        DataSourse[DataSourse.Count - 1].AddBtVisibility = Visibility.Visible;
                    else 
                    {
                        DataSourse.Add(new ConfigModel() { AddBtVisibility = Visibility.Visible });
                    }
                });
            }
        }



        /// <summary>
        /// 选择全部或者取消选择全部
        /// </summary>
        public ICommand SelectOrUnSelectAllCommand
        {
            get
            {
                return new RelayCommand<System.Windows.Controls.CheckBox>((e) =>
                {
                    if (e.IsChecked is true) //选择全部
                    {
                        SelectOrUnSelectItem(this.DataSourse, true);
                    }
                    else  //取消选择全部
                    {
                        SelectOrUnSelectItem(this.DataSourse, false);
                    }
                });
            }
        }

        #endregion

        #region 私有方法
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="Id">唯一标识</param>
        private void Delete(string Id)
        {
            for (var i = 0; i < DataSourse.Count; i++)
            {
                if (DataSourse[i].Id == Id)
                {
                    ReSaveData();
                    DataSourse.Remove(DataSourse[i]);
                    break;
                }
            }
            if (DataSourse.Count == 0) 
            {
                ReSaveData();
            }
        }

        /// <summary>
        /// 重写保存数据
        /// </summary>
        private void ReSaveData()
        {
            StringBuilder @string = new StringBuilder();
            @string.AppendLine($"name\tinitialvalue\t\tunit\tvalue");
            for (var i = 0; i < DataSourse.Count; i++)
            {
                if (DataSourse[i].IsValidated())
                {
                    @string.AppendLine($"{DataSourse[i].Name}\t{DataSourse[i].InitialValue}\t\t{DataSourse[i].Unit}\t{DataSourse[i].Value}");
                }
            }
            if (@string.Length > 0)
            {
                ReadWriteTxtHelper.WriteTxt(@string.ToString(), true);
            }
        }

        /// <summary>
        /// 选择全部数据或者取消选择全部数据
        /// </summary>
        /// <param name="configsData">操作的配置数据</param>
        /// <param name="isSelected">是否选中</param>
        private void SelectOrUnSelectItem(IEnumerable<ConfigModel> configsData, bool isSelected = false)
        {
            foreach (var model in configsData)
            {
                model.IsSelected = isSelected;
            }
        }

        /// <summary>
        /// DataGrid自动滚动到最后一行
        /// </summary>
        private void DataGridScrollToEnd()
        {
            if (DataGridVi.Items.Count > 0)
            {
                Decorator border = VisualTreeHelper.GetChild(DataGridVi, 0) as Decorator;
                if (border != null)
                {
                    if ((border.Child as ScrollViewer) != null)
                    {
                        (border.Child as ScrollViewer).ScrollToEnd();
                    }
                }
            }
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="msg">信息</param>
        private void SendData(string msg)
        {
            byte[] data = Encoding.Default.GetBytes(msg);
            //发送数据
            _client.CommSend(data, data.Length);
        }
        #endregion
    }
}
